package gateway.route;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.yaml.snakeyaml.Yaml;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.InputStream;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;



@Component
public class YamlRouteDefinitionLoader implements RouteDefinitionRepository {
    @Value("${routes.file}")
    String routeFile;
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(loadRoutesFromYaml(routeFile));
    }

    public static void main(String[] args) {
        new YamlRouteDefinitionLoader().loadRoutesFromYaml("/Users/mac/IdeaProjects/SpringCloudGateWay/src/main/resources/routes.yml");
    }

    public  List<RouteDefinition> loadRoutesFromYaml(String yamlFilePath) {
        Yaml yaml = new Yaml();
        try (InputStream inputStream = Files.newInputStream(Paths.get(yamlFilePath))) {
            Map<String, List<Map<String, Object>>> yamlData = yaml.load(inputStream);
            List<RouteDefinition> routeDefinitions = new ArrayList<>();
            List<Map<String, Object>> routes = yamlData.get("routes");
            for (Map<String, Object> routeMap : routes) {
                RouteDefinition routeDefinition = new RouteDefinition();
                routeDefinition.setId((String) routeMap.get("id"));
                routeDefinition.setUri(URI.create((String) routeMap.get("uri")));
                // 假设predicates和filters是列表，并且每个列表项都是一个Map
                routeDefinition.setPredicates(parsePredicates((List<String>) routeMap.get("predicates")));
                routeDefinition.setFilters(parseFilters((List<String>) routeMap.get("filters")));
                routeDefinition.setOrder((Integer) routeMap.getOrDefault("order",0));
                routeDefinitions.add(routeDefinition);
            }
            return routeDefinitions;
        } catch (Exception e) {
            throw new RuntimeException("Error loading routes from YAML file", e);
        }
    }

    // 解析predicates和filters的方法（这里只是简单示例，具体实现取决于你的YAML结构）
    public List<PredicateDefinition> parsePredicates(List<String> list )  {

        if (CollectionUtils.isEmpty(list)) {
            return Collections.EMPTY_LIST;
        }


        List<PredicateDefinition> predicateDefinitions = new ArrayList<>();
        for (String predicate : list) {
            if (StringUtils.isEmpty(predicate)) {
                continue;
            }
            PredicateDefinition definition = new PredicateDefinition(predicate);
            predicateDefinitions.add(definition);
        }
        return predicateDefinitions;
    }

    private List<FilterDefinition> parseFilters(List<String> list )  {
        if (StringUtils.isEmpty(list)) {
            return Collections.EMPTY_LIST;
        }

        List<FilterDefinition> filterDefinitions = new ArrayList<>();
        for (String filter : list) {
            if (StringUtils.isEmpty(filter)) {
                continue;
            }
            FilterDefinition definition = new FilterDefinition(filter);
            filterDefinitions.add(definition);
        }
        return filterDefinitions;
    }


    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return null;
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return null;
    }
}